home *** CD-ROM | disk | FTP | other *** search
/ Visual Basic Graphics Programming (2nd Edition) / Visual Basic Graphics Programming 2nd Edition.iso / Src / Ch7 / Warp.frm (.txt) < prev    next >
Encoding:
Visual Basic Form  |  1999-06-06  |  12.9 KB  |  370 lines

  1. VERSION 5.00
  2. Object = "{F9043C88-F6F2-101A-A3C9-08002B2F49FB}#1.2#0"; "COMDLG32.OCX"
  3. Begin VB.Form frmWarp 
  4.    Caption         =   "Warp []"
  5.    ClientHeight    =   2895
  6.    ClientLeft      =   165
  7.    ClientTop       =   735
  8.    ClientWidth     =   3120
  9.    LinkTopic       =   "Form2"
  10.    ScaleHeight     =   2895
  11.    ScaleWidth      =   3120
  12.    StartUpPosition =   3  'Windows Default
  13.    Begin VB.ComboBox cboTransformation 
  14.       Height          =   315
  15.       ItemData        =   "Warp.frx":0000
  16.       Left            =   120
  17.       List            =   "Warp.frx":0016
  18.       Style           =   2  'Dropdown List
  19.       TabIndex        =   2
  20.       Top             =   120
  21.       Width           =   2415
  22.    End
  23.    Begin VB.PictureBox picResult 
  24.       Height          =   2295
  25.       Left            =   840
  26.       ScaleHeight     =   149
  27.       ScaleMode       =   3  'Pixel
  28.       ScaleWidth      =   157
  29.       TabIndex        =   1
  30.       Top             =   1320
  31.       Visible         =   0   'False
  32.       Width           =   2415
  33.    End
  34.    Begin MSComDlg.CommonDialog dlgOpenFile 
  35.       Left            =   0
  36.       Top             =   360
  37.       _ExtentX        =   847
  38.       _ExtentY        =   847
  39.       _Version        =   393216
  40.    End
  41.    Begin VB.PictureBox picOriginal 
  42.       AutoSize        =   -1  'True
  43.       Height          =   2295
  44.       Left            =   120
  45.       ScaleHeight     =   149
  46.       ScaleMode       =   3  'Pixel
  47.       ScaleWidth      =   157
  48.       TabIndex        =   0
  49.       Top             =   480
  50.       Width           =   2415
  51.    End
  52.    Begin VB.Menu mnuFile 
  53.       Caption         =   "&File"
  54.       Begin VB.Menu mnuFileOpen 
  55.          Caption         =   "&Open..."
  56.          Shortcut        =   ^O
  57.       End
  58.       Begin VB.Menu mnuFileSaveAs 
  59.          Caption         =   "Save &As..."
  60.          Shortcut        =   ^A
  61.       End
  62.    End
  63. Attribute VB_Name = "frmWarp"
  64. Attribute VB_GlobalNameSpace = False
  65. Attribute VB_Creatable = False
  66. Attribute VB_PredeclaredId = True
  67. Attribute VB_Exposed = False
  68. Option Explicit
  69. Private Selection As Integer
  70. Private Rmax As Single
  71. Private Xmid As Single
  72. Private Ymid As Single
  73. ' Map the output pixel (ix_out, iy_out) to the input
  74. ' pixel (x_in, y_in).
  75. Private Sub MapPixel(ByVal ix_out As Single, ByVal iy_out As Single, ByRef x_in As Single, ByRef y_in As Single)
  76. Const PI = 3.14159265
  77. Const PI_OVER_2 = PI / 2
  78. Const K = 50
  79. Const OFFSET = -PI_OVER_2
  80. Dim dx As Single
  81. Dim dy As Single
  82. Dim r1 As Single
  83. Dim r2 As Single
  84. Dim theta As Single
  85. Dim wid As Single
  86.     Select Case Selection
  87.         Case 0 ' Fish Eye
  88.             dx = ix_out - Xmid
  89.             dy = iy_out - Ymid
  90.             r1 = Sqr(dx * dx + dy * dy)
  91.             If r1 = 0 Then
  92.                 x_in = Xmid
  93.                 y_in = Ymid
  94.             Else
  95.                 r2 = Rmax / 2 * (1 / (1 - r1 / Rmax) - 1)
  96.                 x_in = dx * r2 / r1 + Xmid
  97.                 y_in = dy * r2 / r1 + Ymid
  98.             End If
  99.         Case 1 ' Twist
  100.             dx = ix_out - Xmid
  101.             dy = iy_out - Ymid
  102.             r1 = Sqr(dx * dx + dy * dy)
  103.             If r1 = 0 Then
  104.                 x_in = 0
  105.                 y_in = 0
  106.             Else
  107.                 theta = ATan2(dx, dy) - r1 / K - OFFSET
  108.                 x_in = r1 * Cos(theta)
  109.                 y_in = r1 * Sin(theta)
  110.             End If
  111.             x_in = x_in + Xmid
  112.             y_in = y_in + Ymid
  113.         Case 2 ' Wave
  114.             x_in = ix_out
  115.             y_in = iy_out - 10 * (Sin(ix_out / 50 * PI) + 1) + 5
  116.         Case 3 ' Small Top
  117.             dx = Xmid - ix_out
  118.             dx = dx * Ymid * 2 / (iy_out + 1)
  119.             x_in = Xmid - dx
  120.             y_in = iy_out
  121.         Case 4 ' Wiggles
  122.             dx = Xmid - ix_out
  123.             dx = dx * (Sin(iy_out / 50 * PI) / 2 + 1.5)
  124.             x_in = Xmid - dx
  125.             y_in = iy_out
  126.         Case 5 ' Double Wave
  127.             x_in = ix_out - 10 * (Sin(iy_out / 50 * PI) + 1) + 5
  128.             y_in = iy_out - 10 * (Sin(ix_out / 50 * PI) + 1) + 5
  129.         Case Else
  130.             x_in = ix_out
  131.             y_in = iy_out
  132.     End Select
  133. End Sub
  134. ' Transform the image.
  135. Private Sub TransformImage(ByVal pic_from As PictureBox, ByVal pic_to As PictureBox)
  136. Dim white_pixel As RGBTriplet
  137. Dim input_pixels() As RGBTriplet
  138. Dim result_pixels() As RGBTriplet
  139. Dim bits_per_pixel As Integer
  140. Dim ix_max As Single
  141. Dim iy_max As Single
  142. Dim x_in As Single
  143. Dim y_in As Single
  144. Dim ix_out As Long
  145. Dim iy_out As Long
  146. Dim ix_in As Long
  147. Dim iy_in As Long
  148. Dim dx As Single
  149. Dim dy As Single
  150. Dim dx1 As Single
  151. Dim dx2 As Single
  152. Dim dy1 As Single
  153. Dim dy2 As Single
  154. Dim v11 As Integer
  155. Dim v12 As Integer
  156. Dim v21 As Integer
  157. Dim v22 As Integer
  158.     ' Set the white pixel's value.
  159.     With white_pixel
  160.         .rgbRed = 255
  161.         .rgbGreen = 255
  162.         .rgbBlue = 255
  163.     End With
  164.     ' Get the pixels from pic_from.
  165.     GetBitmapPixels pic_from, input_pixels, bits_per_pixel
  166.     ' Get the pixels from pic_to.
  167.     GetBitmapPixels pic_to, result_pixels, bits_per_pixel
  168.     ' Get the original image's bounds.
  169.     ix_max = pic_from.ScaleWidth - 2
  170.     iy_max = pic_from.ScaleHeight - 2
  171.     ' Calculate the output pixel values.
  172.     For iy_out = 0 To pic_to.ScaleHeight - 1
  173.         For ix_out = 0 To pic_to.ScaleWidth - 1
  174.             ' Map the pixel value from
  175.             ' (ix_out, iy_out) to (x_in, y_in).
  176.             MapPixel ix_out, iy_out, x_in, y_in
  177.             ' Interpolate to find the pixel's value.
  178.             ' Find the nearest integral position.
  179.             ix_in = Int(x_in)
  180.             iy_in = Int(y_in)
  181.             ' See if this is out of bounds.
  182.             If (ix_in < 0) Or (ix_in > ix_max) Or _
  183.                (iy_in < 0) Or (iy_in > iy_max) _
  184.             Then
  185.                 ' The point is outside the image.
  186.                 ' Use white.
  187.                 result_pixels(ix_out, iy_out) = white_pixel
  188.             Else
  189.                 ' The point lies within the image.
  190.                 ' Calculate its value.
  191.                 dx1 = x_in - ix_in
  192.                 dy1 = y_in - iy_in
  193.                 dx2 = 1# - dx1
  194.                 dy2 = 1# - dy1
  195.                 With result_pixels(ix_out, iy_out)
  196.                     ' Calculate the red value.
  197.                     v11 = input_pixels(ix_in, iy_in).rgbRed
  198.                     v12 = input_pixels(ix_in, iy_in + 1).rgbRed
  199.                     v21 = input_pixels(ix_in + 1, iy_in).rgbRed
  200.                     v22 = input_pixels(ix_in + 1, iy_in + 1).rgbRed
  201.                     .rgbRed = _
  202.                         v11 * dx2 * dy2 + v12 * dx2 * dy1 + _
  203.                         v21 * dx1 * dy2 + v22 * dx1 * dy1
  204.         
  205.                     ' Calculate the green value.
  206.                     v11 = input_pixels(ix_in, iy_in).rgbGreen
  207.                     v12 = input_pixels(ix_in, iy_in + 1).rgbGreen
  208.                     v21 = input_pixels(ix_in + 1, iy_in).rgbGreen
  209.                     v22 = input_pixels(ix_in + 1, iy_in + 1).rgbGreen
  210.                     .rgbGreen = _
  211.                         v11 * dx2 * dy2 + v12 * dx2 * dy1 + _
  212.                         v21 * dx1 * dy2 + v22 * dx1 * dy1
  213.                     ' Calculate the blue value.
  214.                     v11 = input_pixels(ix_in, iy_in).rgbBlue
  215.                     v12 = input_pixels(ix_in, iy_in + 1).rgbBlue
  216.                     v21 = input_pixels(ix_in + 1, iy_in).rgbBlue
  217.                     v22 = input_pixels(ix_in + 1, iy_in + 1).rgbBlue
  218.                     .rgbBlue = _
  219.                         v11 * dx2 * dy2 + v12 * dx2 * dy1 + _
  220.                         v21 * dx1 * dy2 + v22 * dx1 * dy1
  221.                 End With
  222.             End If
  223.         Next ix_out
  224.     Next iy_out
  225.     ' Set pic_to's pixels.
  226.     SetBitmapPixels pic_to, bits_per_pixel, result_pixels
  227.     pic_to.Picture = pic_to.Image
  228. End Sub
  229. ' Arrange the controls.
  230. Private Sub ArrangeControls()
  231. Dim wid As Single
  232.     ' Position the result PictureBox.
  233.     picResult.Move _
  234.         picOriginal.Left + picOriginal.Width + 120, _
  235.         picOriginal.Top, picOriginal.Width, picOriginal.Height
  236.     picResult.Line (0, 0)-(picResult.ScaleWidth, picResult.ScaleHeight), _
  237.         picResult.BackColor, BF
  238.     picResult.Picture = picResult.Image
  239.     picResult.Visible = True
  240.     ' This makes the image resize itself to
  241.     ' fit the picture.
  242.     picResult.Picture = picResult.Image
  243.     ' Make the form big enough.
  244.     If cboTransformation.Left + cboTransformation.Width > picResult.Left + picResult.Width Then
  245.         wid = cboTransformation.Left + cboTransformation.Width
  246.     Else
  247.         wid = picResult.Left + picResult.Width
  248.     End If
  249.     Move Left, Top, wid + 237, _
  250.         picResult.Top + picResult.Height + 816
  251.     DoEvents
  252. End Sub
  253. ' Apply the transformation.
  254. Private Sub cboTransformation_Click()
  255.     ' Do nothing if no picture is loaded.
  256.     If picOriginal.Picture = 0 Then Exit Sub
  257.     ' Prepare for the transformation.
  258.     Selection = cboTransformation.ListIndex
  259.     Xmid = picOriginal.ScaleWidth / 2
  260.     Ymid = picOriginal.ScaleHeight / 2
  261.     Rmax = picOriginal.ScaleWidth * 0.75
  262.     ' Arrange the controls.
  263.     ArrangeControls
  264.     Screen.MousePointer = vbHourglass
  265.     picResult.Line (0, 0)-(picResult.ScaleWidth, picResult.ScaleHeight), _
  266.         picResult.BackColor, BF
  267.     DoEvents
  268.     ' Transform the image.
  269.     TransformImage picOriginal, picResult
  270.     Screen.MousePointer = vbDefault
  271. End Sub
  272. ' Start in the current directory.
  273. Private Sub Form_Load()
  274.     picOriginal.AutoSize = True
  275.     picOriginal.ScaleMode = vbPixels
  276.     picOriginal.AutoRedraw = True
  277.     picResult.ScaleMode = vbPixels
  278.     picResult.AutoRedraw = True
  279.     dlgOpenFile.CancelError = True
  280.     dlgOpenFile.InitDir = App.Path
  281.     dlgOpenFile.Filter = _
  282.         "Bitmaps (*.bmp)|*.bmp|" & _
  283.         "GIFs (*.gif)|*.gif|" & _
  284.         "JPEGs (*.jpg)|*.jpg;*.jpeg|" & _
  285.         "Icons (*.ico)|*.ico|" & _
  286.         "Cursors (*.cur)|*.cur|" & _
  287.         "Run-Length Encoded (*.rle)|*.rle|" & _
  288.         "Metafiles (*.wmf)|*.wmf|" & _
  289.         "Enhanced Metafiles (*.emf)|*.emf|" & _
  290.         "Graphic Files|*.bmp;*.gif;*.jpg;*.jpeg;*.ico;*.cur;*.rle;*.wmf;*.emf|" & _
  291.         "All Files (*.*)|*.*"
  292.     Width = picOriginal.Left + picOriginal.Width + 120 + Width - ScaleWidth
  293.     Height = picOriginal.Top + picOriginal.Height + 120 + Height - ScaleHeight
  294. End Sub
  295. ' Load the indicated file.
  296. Private Sub mnuFileOpen_Click()
  297. Dim file_name As String
  298.     ' Let the user select a file.
  299.     On Error Resume Next
  300.     dlgOpenFile.Flags = cdlOFNFileMustExist + cdlOFNHideReadOnly
  301.     dlgOpenFile.ShowOpen
  302.     If Err.Number = cdlCancel Then
  303.         Exit Sub
  304.     ElseIf Err.Number <> 0 Then
  305.         Beep
  306.         MsgBox "Error selecting file.", , vbExclamation
  307.         Exit Sub
  308.     End If
  309.     On Error GoTo 0
  310.     Screen.MousePointer = vbHourglass
  311.     DoEvents
  312.     file_name = Trim$(dlgOpenFile.FileName)
  313.     dlgOpenFile.InitDir = Left$(file_name, Len(file_name) _
  314.         - Len(dlgOpenFile.FileTitle) - 1)
  315.     Caption = "Warp [" & dlgOpenFile.FileTitle & "]"
  316.     ' Open the original file.
  317.     On Error GoTo LoadError
  318.     picOriginal.Picture = LoadPicture(file_name)
  319.     On Error GoTo 0
  320.     picOriginal.Picture = picOriginal.Image
  321.     ' Hide picResult.
  322.     picResult.Visible = False
  323.     If cboTransformation.Left + cboTransformation.Width > picOriginal.Left + picOriginal.Width Then
  324.         Width = cboTransformation.Left + cboTransformation.Width + 120 + Width - ScaleWidth
  325.     Else
  326.         Width = picOriginal.Left + picOriginal.Width + 120 + Width - ScaleWidth
  327.     End If
  328.     Height = picOriginal.Top + picOriginal.Height + 120 + Height - ScaleHeight
  329.     Screen.MousePointer = vbDefault
  330.     Exit Sub
  331. LoadError:
  332.     Screen.MousePointer = vbDefault
  333.     MsgBox "Error " & Format$(Err.Number) & _
  334.         " opening file '" & file_name & "'" & vbCrLf & _
  335.         Err.Description
  336. End Sub
  337. ' Save the transformed image.
  338. Private Sub mnuFileSaveAs_Click()
  339. Dim file_name As String
  340.     ' Let the user select a file.
  341.     On Error Resume Next
  342.     dlgOpenFile.Flags = cdlOFNOverwritePrompt + cdlOFNHideReadOnly
  343.     dlgOpenFile.ShowSave
  344.     If Err.Number = cdlCancel Then
  345.         Exit Sub
  346.     ElseIf Err.Number <> 0 Then
  347.         Beep
  348.         MsgBox "Error selecting file.", , vbExclamation
  349.         Exit Sub
  350.     End If
  351.     On Error GoTo 0
  352.     Screen.MousePointer = vbHourglass
  353.     DoEvents
  354.     file_name = Trim$(dlgOpenFile.FileName)
  355.     dlgOpenFile.InitDir = Left$(file_name, Len(file_name) _
  356.         - Len(dlgOpenFile.FileTitle) - 1)
  357.     Caption = "Warp [" & dlgOpenFile.FileTitle & "]"
  358.     ' Save the transformed image into the file.
  359.     On Error GoTo SaveError
  360.     SavePicture picResult.Picture, file_name
  361.     On Error GoTo 0
  362.     Screen.MousePointer = vbDefault
  363.     Exit Sub
  364. SaveError:
  365.     Screen.MousePointer = vbDefault
  366.     MsgBox "Error " & Format$(Err.Number) & _
  367.         " saving file '" & file_name & "'" & vbCrLf & _
  368.         Err.Description
  369. End Sub
  370.